home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 25 / AACD 25.iso / AACD / Magazine / Online / QMail / source / ipme.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-15  |  2.2 KB  |  96 lines

  1. #include <sys/types.h>
  2. #include <sys/param.h>
  3. #include <sys/time.h>
  4. #include <sys/ioctl.h>
  5. #include <sys/socket.h>
  6. #include <net/if.h>
  7. #include <netinet/in.h>
  8. #ifndef SIOCGIFCONF /* whatever works */
  9. #include <sys/sockio.h>
  10. #endif
  11. #include "hassalen.h"
  12. #include "byte.h"
  13. #include "ip.h"
  14. #include "ipalloc.h"
  15. #include "stralloc.h"
  16. #include "ipme.h"
  17.  
  18. static int ipmeok = 0;
  19. ipalloc ipme = {0};
  20.  
  21. int ipme_is(ip)
  22. struct ip_address *ip;
  23. {
  24.   int i;
  25.   if (ipme_init() != 1) return -1;
  26.   for (i = 0;i < ipme.len;++i)
  27.     if (byte_equal(&ipme.ix[i].ip,4,ip))
  28.       return 1;
  29.   return 0;
  30. }
  31.  
  32. static stralloc buf = {0};
  33.  
  34. int ipme_init()
  35. {
  36.   struct ifconf ifc;
  37.   char *x;
  38.   struct ifreq *ifr;
  39.   struct sockaddr_in *sin;
  40.   int len;
  41.   int s;
  42.   struct ip_mx ix;
  43.  
  44.   if (ipmeok) return 1;
  45.   if (!ipalloc_readyplus(&ipme,0)) return 0;
  46.   ipme.len = 0;
  47.   ix.pref = 0;
  48.  
  49.   if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1) return -1;
  50.  
  51.   len = 256;
  52.   for (;;) {
  53.     if (!stralloc_ready(&buf,len)) { close(s); return 0; }
  54.     buf.len = 0;
  55.     ifc.ifc_buf = buf.s;
  56.     ifc.ifc_len = len;
  57.     if (ioctl(s,SIOCGIFCONF,&ifc) >= 0) /* > is for System V */
  58.       if (ifc.ifc_len + sizeof(*ifr) + 64 < len) { /* what a stupid interface */
  59.         buf.len = ifc.ifc_len;
  60.         break;
  61.       }
  62.     if (len > 200000) { close(s); return -1; }
  63.     len += 100 + (len >> 2);
  64.   }
  65.   x = buf.s;
  66.   while (x < buf.s + buf.len) {
  67.     ifr = (struct ifreq *) x;
  68. #ifdef HASSALEN
  69.     len = sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len;
  70.     if (len < sizeof(*ifr))
  71.       len = sizeof(*ifr);
  72.     if (ifr->ifr_addr.sa_family == AF_INET) {
  73.       sin = (struct sockaddr_in *) &ifr->ifr_addr;
  74.       byte_copy(&ix.ip,4,&sin->sin_addr);
  75.       if (ioctl(s,SIOCGIFFLAGS,x) == 0)
  76.         if (ifr->ifr_flags & IFF_UP)
  77.           if (!ipalloc_append(&ipme,&ix)) { close(s); return 0; }
  78.     }
  79. #else
  80.     len = sizeof(*ifr);
  81.     if (ioctl(s,SIOCGIFFLAGS,x) == 0)
  82.       if (ifr->ifr_flags & IFF_UP)
  83.         if (ioctl(s,SIOCGIFADDR,x) == 0)
  84.       if (ifr->ifr_addr.sa_family == AF_INET) {
  85.         sin = (struct sockaddr_in *) &ifr->ifr_addr;
  86.         byte_copy(&ix.ip,4,&sin->sin_addr);
  87.         if (!ipalloc_append(&ipme,&ix)) { close(s); return 0; }
  88.       }
  89. #endif
  90.     x += len;
  91.   }
  92.   close(s);
  93.   ipmeok = 1;
  94.   return 1;
  95. }
  96.